package com.interceptor;

import com.entity.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.util.CurrentUser;
import com.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //前后端分离项目，有些复杂的请求，会先发送一个预检请求，这个请求直接放行
        //请求方式：POST,GET,PUT,DELETE,OPTIONS
        if(request.getMethod().equals("OPTIONS")){
            log.info("进入拦截器---OPTIONS请求放行");
            return true;
        }


        Result result = null;
        ObjectMapper objectMapper = new ObjectMapper();
        String str = null;
        response.setContentType("text/html;charset=utf-8");

        //获取请求头中的token，校验
        String token = request.getHeader("token");

        if(StringUtils.isEmpty(token) && !JwtUtil.verify(token)){
            result = new Result(401, "先登录", "not authentication");
            //将对象序列化成JSON，响应给前端，JSON工具：jsonlib,gson,fastjson,jackson(SpringMVC内置的)
            str = objectMapper.writeValueAsString(result);
            response.getWriter().write(str);
            log.info("token无效，拦截未登录");
            return false;
        }

        log.info("token有效,验证是否过期");
        if(JwtUtil.isExpire(token)){
            log.info("token有效,过期,查询redis");
            if(redisTemplate.hasKey("token:" + token)){

                    log.info("token有效,token过期,redis有token，放行");
                    log.info("当前token={}",token);
                    //获取当前用户信息。
                    CurrentUser.token=token;

                    //删除上次redis的长token
                    redisTemplate.delete("token:" + token);
                    //重新生成token
                    token = JwtUtil.create(JwtUtil.getEid(token), JwtUtil.getEname(token));
                    //长token重新存入redis
                    redisTemplate.opsForValue().set("token:" + token, "xxx", 60*24, TimeUnit.MINUTES);

                    log.info("成功生成新的token");
                    response.setHeader("token", token);
                    response.setHeader("Access-Control-Expose-Headers", "*");


                    return true;

            }else{
                    log.info("token有效,过期,redis无token,拦截");
                    result = new Result(401, "超时未操作，请重新登录", "not authentication");
                    //将对象序列化成JSON，响应给前端，JSON工具：jsonlib,gson,fastjson,jackson(SpringMVC内置的)
                    str = objectMapper.writeValueAsString(result);
                    response.getWriter().write(str);
                    return false;
            }
        }
        log.info("当前token={}",token);
        //获取当前用户信息。
        CurrentUser.token=token;
        log.info("token有效,没有过期,放行");
        return true;
    }
}
